package nl.haemers.timer 
{
	import flash.errors.IllegalOperationError;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	import flash.events.TimerEvent;
	
	import nl.haemers.timer.SubTime;
	/**
	 * ...
	 * @author Jonathan Haemers
	 */
	public class StopWatch
	{
		//- stopwatch with reset, stop, subtime start.
		protected var _countDown			:Boolean;
		protected var _running				:Boolean;
		protected var _reset				:Boolean;
		
		protected var _maxTime				:Number;
		protected var _countDownTime		:Number;
		protected var startTime				:Number;		
		protected var _currentTime			:Number;
		
		protected var stoppedTime			:Number;
		protected var stopTime				:Number;
		
		protected var subTime				:Number;
		protected var lastSubtime			:Number;
		protected var _subTimes				:Vector.<SubTime>;
		
		public function StopWatch() 
		{
			_countDownTime = 0;
			reset();
		}
		
		public function start() : void
		{
			if (_running)
			{
				reset();
			}
			
			if (_reset)
			{
				startTime = getStartTime();
			}
			else
			{
				stoppedTime += getStopTime();
			}
			
			_reset = false;
			_running = true;
			
		}
		
		public function reset() : void
		{
			startTime = getResetStartTime();
			stopTime = 0;
			stoppedTime = 0;
			
			_subTimes = new Vector.<SubTime>();
			lastSubtime = getResetLastSubTime();
			
			_running = false;
			_reset = true;
		}
		
		public function stop() : void
		{
			if (_running)
			{
				stopTime = getTimer();
				_running = false;
			}
		}
		
		public function getSubTime() : SubTime
		{
			var subTime:SubTime = new SubTime();
			subTime.currentTime = currentTime;
			subTime.subTime = getCurrentSubTime();
			
			_subTimes.push(subTime);
			lastSubtime = subTime.currentTime;
			
			return subTime;
		}
		
		public function getHoures() : int
		{
			return int(currentTime * .0000036);
		}
		
		public function getMinutes() : int 
		{
			return int(currentTime * .00006);
		}
		
		public function getSeconds() : int
		{
			return int(currentTime * .0001);
		}
		
		/** Getters & Setters **/
		public function get countDownTime() : Number
		{ 
			return _countDownTime;
		}
		public function set countDownTime( value:Number ) : void 
		{
			_countDownTime = value;
			reset();
		}
		
		public function get maxTime() : Number
		{ 
			return _maxTime;
		}
		public function set maxTime( value:Number ) : void 
		{
			_maxTime = value;
		}
		
		public function get countDown() : Boolean
		{ 
			return _countDown;
		}
		public function set countDown( value:Boolean ) : void 
		{
			_countDown = value;
			reset();
		}
		
		public function get subTimes() : Vector.<SubTime>
		{ 
			return _subTimes;
		}
		
		public function get currentTime() : Number
		{ 
			if (_running)
			{
				_currentTime = getRunningTime();
			}
			else
			{
				 _currentTime = getCurrentStopTime();
			}
			return _currentTime;
		}
		
		/** Protected methods **/
		protected function getStartTime() : Number
		{
			return (_countDown) ? (_countDownTime + getTimer()) : getTimer();
		}
		
		protected function getResetStartTime() : Number
		{
			return (_countDown) ? _countDownTime : 0;
		}
		
		protected function getRunningTime() : Number
		{
			return (_countDown) ? (startTime - getTimer() + stoppedTime) : (getTimer() - startTime - stoppedTime);
		}
		
		protected function getStopTime() : Number
		{
			return getTimer() - stopTime;
		}
		
		protected function getCurrentStopTime() : Number 
		{
			return (_countDown) ? (startTime - stopTime + stoppedTime) : (stopTime - startTime - stoppedTime);
		}
		
		protected function getCurrentSubTime() : Number
		{
			return (_countDown) ? (lastSubtime - currentTime) : (currentTime - lastSubtime);
		}
		
		protected function getResetLastSubTime() : Number
		{
			return (_countDown) ? _countDownTime : 0;
		}
	}
}